package everyday;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 函数式编程相关
 *
 * @author gaojie
 * @date 2023-05-11
 */
public class FunctionOperation {

    /**
     * 测试 Consumer 的使用
     */
    @Test
    void test01() {
        final ArrayList<String> objects = new ArrayList<>();
        objects.add("AAA");
        objects.add("BBB");
        objects.add("CCC");
        batch(e -> {
            System.out.printf("执行业务逻辑【%s】-开始%n", e);
            if ("BBB".equals(e)) {
                throw new RuntimeException("程序运行异常");
            }
            System.out.printf("执行业务逻辑【%s】-完成%n", e);
        }, objects);
    }

    <T> void batch(Consumer<T> action, List<T> list) {
        System.out.println("进入batch方法");
        list.forEach(e -> {
            try {
                action.accept(e);
                System.out.println("执行成功");
            } catch (Exception ex) {
                System.out.printf("执行失败：%s%n", ex.getMessage());
            }
        });
        System.out.println("完成batch方法");
    }

    /**
     * 测试 consumer 无参的使用
     */
    @Test
    void test02() {
        distributeLockExecute(e -> System.out.println("我是业务操作"),"key");
    }

    /**
     * 分布式锁执行业务逻辑
     *
     * @param action 业务逻辑
     * @param key    锁key
     */
    void distributeLockExecute(Consumer<?> action, String key) {
        String value = String.format("lock:%s", key);
        System.out.printf("加锁成功：[%s-%s]%n", key, value);
        try {
            System.out.println("执行业务逻辑开始");
            action.accept(null);
            System.out.println("执行业务逻辑完成");
        } finally {
            System.out.printf("释放锁：%s", value);
        }
    }

    /**
     * 测试 Function 的使用
     */
    @Test
    void test03() {
        final Person person = new Person("AA", 180);
        final String s = getVal(person, Person::getName);
        System.out.println(s);
    }

    <T, K> K getVal(T t, Function<T, K> keyMapper) {
        return keyMapper.apply(t);
    }
}
